package dataBase

import (
	"fmt"
	"gopkg.in/mgo.v2"
	"log"
	"time"
)


const (
	//dbhost    = "10.2.5.1:27000"
	//dbhost2 ="10.2.5.1:27001"
	dbhost2 ="127.0.0.1:27017"
	authdb    = "admin"
	//authuser  = "root"
	//authpass  = "root"
	timeout   = 2 * time.Second
	poollimit = 4096
)

var globalS *mgo.Session

func init() {
	dialInfo := &mgo.DialInfo{
		Addrs:     []string{dbhost2},
		Timeout:   timeout,
		Source:    authdb,
		//Username:  authuser,
		//Password:  authpass,
		PoolLimit: poollimit,
	}

	s, err := mgo.DialWithInfo(dialInfo)
	if err != nil {
		log.Fatalf("创建MongDB链接: %s\n", err)
	}
	globalS = s
}

func connect(db, collection string) (*mgo.Session, *mgo.Collection) {
	ms := globalS.Copy()
	c := ms.DB(db).C(collection)
	ms.SetMode(mgo.Monotonic, true)
	return ms, c
}

func IsEmpty(db, collection string) bool {
	ms, c := connect(db, collection)
	defer ms.Close()
	count, err := c.Count()
	if err != nil {
		log.Fatal(err)
	}
	return count == 0
}

func Count(db, collection string, query interface{}) (int, error) {
	ms, c := connect(db, collection)
	defer ms.Close()
	return c.Find(query).Count()
}

func Insert(db, collection string, doc interface{},a chan int )  {
	ms, c := connect(db, collection)
	defer ms.Close()
	err:=c.Insert(doc)
	if(err!=nil){
		fmt.Print(err)
		a<-0
		return
	}
	a <-1
}
func Inserts(db, collection string, doc interface{} ) error {
	ms, c := connect(db, collection)
	defer ms.Close()
	err:=c.Insert(doc)
	return  err
}
func InsertAll(db, collection string, doc []interface{},a chan int )  {
	ms, c := connect(db, collection)
	defer ms.Close()
	//fmt.Printf("测试:%v",doc)
	err:=c.Insert(doc...)
	if(err!=nil){
		fmt.Print(err)
		a<-0
		return
	}
	a <-1
}
func GetStats(){

}
func DropCollection()error{
	mdb:=globalS.DB("db")
	err:=mdb.DropDatabase()
	return err
	}
//添加索引
func EnsureIndex(db,collection string ,index mgo.Index)error{
	ms,c:=connect(db,collection)
	defer ms.Close()
	err:=c.EnsureIndex(index)
	if err!=nil {
		return err
	}
	return nil
}
//删除索引
func DropIndex(db,collection string ,index string)error{
	ms,c:=connect(db,collection)
	defer ms.Close()
	err:=c.DropIndex(index)
	if err!=nil {
		return err
	}
	return nil
}

func FindOne(db, collection string, query, selector, result interface{}) error {
	ms, c := connect(db, collection)
	defer ms.Close()

	return c.Find(query).Select(selector).One(result)
}
func FindTespaper(db, collection string, query, selector, result interface{},limet ,skip int) error {
	ms, c := connect(db, collection)
	defer ms.Close()

	return c.Find(query).Sort("addtime").Limit(limet).Skip(skip).Select(selector).All(result)
}
func FindAll(db, collection string, query, selector, result interface{}) error {
	//var books []Book
	//err := c.Find(bson.M{}).All(&books)
	ms, c := connect(db, collection)
	defer ms.Close()

	return c.Find(query).Select(selector).All(result)
}

func FindPage(db, collection string, page, limit int, query, selector, result interface{}) error {
	ms, c := connect(db, collection)
	defer ms.Close()

	return c.Find(query).Select(selector).Skip(page * limit).Limit(limit).All(result)
}

func Update(db, collection string, selector, update interface{}) error {
	ms, c := connect(db, collection)
	defer ms.Close()

	return c.Update(selector, update)
}

func Upsert(db, collection string, selector, update interface{}) error {
	ms, c := connect(db, collection)
	defer ms.Close()

	_, err := c.Upsert(selector, update)
	return err
	//Persons := make([]interface{}, 10000)
	//fmt.Println(time.Now().UnixNano()/1e6)
	//for i := 0; i < 100; i++ {
	//	for j := i * 10000; j < i*10000+10000; j++ {
	//		Persons[j-i*10000] = &Person{"Ale", "+55 53 8116 9639", strconv.Itoa(int(j))}
	//	}
	//	err = c.Insert(Persons[:]...)
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//
	//}
}
func UpsertS(db, collection string, selector, update interface{},cha chan int)  {
	ms, c := connect(db, collection)
	defer ms.Close()

	_, err := c.Upsert(selector, update)
	if(err!=nil){
		cha<-0
	}else {
		cha<-1
	}
	return
}

func UpdateAll(db, collection string, selector, update interface{}) error {
	ms, c := connect(db, collection)
	defer ms.Close()

	_, err := c.UpdateAll(selector, update)
	return err
}

func Remove(db, collection string, selector interface{}) error {
	ms, c := connect(db, collection)
	defer ms.Close()

	return c.Remove(selector)
}

func RemoveAll(db, collection string, selector interface{}) error {
	ms, c := connect(db, collection)
	defer ms.Close()

	_, err := c.RemoveAll(selector)
	return err
}
